package com.pay.trade.service.impl;

import com.pay.common.result.Result;
import com.pay.trade.dto.PayRequest;
import com.pay.trade.dto.PayResponse;
import com.pay.trade.service.TradeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
@DubboService
public class TradeServiceImpl implements TradeService {
    
    // 模拟交易存储，实际项目中应该使用数据库
    private static final Map<String, PayResponse> tradeStore = new ConcurrentHashMap<>();
    private static final Map<String, String> idempotentStore = new ConcurrentHashMap<>();
    
    @Override
    @Transactional
    public Result<PayResponse> pay(PayRequest request) {
        log.info("发起支付，请求参数：{}", request);
        
        try {
            // 1. 幂等性检查
            String idempotentKey = request.getOrderNo() + "_" + request.getAmount() + "_" + request.getChannel();
            if (idempotentStore.containsKey(idempotentKey)) {
                String existingTradeNo = idempotentStore.get(idempotentKey);
                PayResponse existingTrade = tradeStore.get(existingTradeNo);
                if (existingTrade != null) {
                    log.info("幂等性检查通过，返回已存在的交易，交易号：{}", existingTradeNo);
                    return Result.success(existingTrade);
                }
            }
            
            // 2. 参数校验
            if (request.getOrderNo() == null || request.getOrderNo().trim().isEmpty()) {
                return Result.error("订单号不能为空");
            }
            if (request.getAmount() == null || request.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
                return Result.error("支付金额不能为空或小于等于0");
            }
            if (request.getChannel() == null || request.getChannel().trim().isEmpty()) {
                return Result.error("支付渠道不能为空");
            }
            
            // 3. 支付路由（根据渠道选择支付方式）
            String payChannel = routePaymentChannel(request.getChannel(), request.getAmount());
            
            // 4. 调用支付服务（这里简化处理，实际应该调用具体的支付渠道）
            String tradeNo = generateTradeNo();
            
            PayResponse response = new PayResponse();
            response.setTradeNo(tradeNo);
            response.setOrderNo(request.getOrderNo());
            response.setAmount(request.getAmount());
            response.setStatus("PENDING");
            response.setPayUrl("/pay/redirect/" + tradeNo);
            response.setMessage("支付处理中");
            
            // 5. 记录交易流水
            tradeStore.put(tradeNo, response);
            idempotentStore.put(idempotentKey, tradeNo);
            
            log.info("支付发起成功，交易号：{}，渠道：{}", tradeNo, payChannel);
            
            return Result.success(response);
            
        } catch (Exception e) {
            log.error("发起支付失败", e);
            return Result.error("发起支付失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<PayResponse> queryTrade(String tradeNo) {
        log.info("查询交易，交易号：{}", tradeNo);
        
        try {
            // 参数校验
            if (tradeNo == null || tradeNo.trim().isEmpty()) {
                return Result.error("交易号不能为空");
            }
            
            // 查询交易（模拟从数据库查询）
            PayResponse trade = tradeStore.get(tradeNo);
            if (trade == null) {
                return Result.error("交易不存在");
            }
            
            // 模拟查询支付渠道状态
            String channelStatus = queryChannelStatus(tradeNo);
            if (channelStatus != null) {
                trade.setStatus(channelStatus);
                tradeStore.put(tradeNo, trade);
            }
            
            return Result.success(trade);
            
        } catch (Exception e) {
            log.error("查询交易失败", e);
            return Result.error("查询交易失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<PayResponse> refund(String tradeNo, String amount) {
        log.info("发起退款，交易号：{}，金额：{}", tradeNo, amount);
        
        try {
            // 参数校验
            if (tradeNo == null || tradeNo.trim().isEmpty()) {
                return Result.error("交易号不能为空");
            }
            if (amount == null || amount.trim().isEmpty()) {
                return Result.error("退款金额不能为空");
            }
            
            BigDecimal refundAmount;
            try {
                refundAmount = new BigDecimal(amount);
                if (refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
                    return Result.error("退款金额必须大于0");
                }
            } catch (NumberFormatException e) {
                return Result.error("退款金额格式不正确");
            }
            
            // 查询原交易
            PayResponse originalTrade = tradeStore.get(tradeNo);
            if (originalTrade == null) {
                return Result.error("原交易不存在");
            }
            
            // 检查交易状态
            if (!"SUCCESS".equals(originalTrade.getStatus())) {
                return Result.error("原交易状态不正确，无法退款");
            }
            
            // 检查退款金额
            if (refundAmount.compareTo(originalTrade.getAmount()) > 0) {
                return Result.error("退款金额不能大于原交易金额");
            }
            
            // 生成退款交易号
            String refundTradeNo = "REF" + System.currentTimeMillis() + String.format("%04d", (int)(Math.random() * 10000));
            
            // 创建退款交易记录
            PayResponse refundResponse = new PayResponse();
            refundResponse.setTradeNo(refundTradeNo);
            refundResponse.setOrderNo(originalTrade.getOrderNo());
            refundResponse.setAmount(refundAmount);
            refundResponse.setStatus("PENDING");
            refundResponse.setMessage("退款处理中");
            
            // 保存退款记录
            tradeStore.put(refundTradeNo, refundResponse);
            
            log.info("退款发起成功，退款交易号：{}，原交易号：{}", refundTradeNo, tradeNo);
            
            return Result.success(refundResponse);
            
        } catch (Exception e) {
            log.error("发起退款失败", e);
            return Result.error("发起退款失败：" + e.getMessage());
        }
    }
    
    /**
     * 支付路由
     */
    private String routePaymentChannel(String channel, BigDecimal amount) {
        // 根据渠道和金额进行路由
        if ("WECHAT".equals(channel)) {
            if (amount.compareTo(new BigDecimal("1000")) > 0) {
                return "WECHAT_BANK"; // 大额走银行渠道
            } else {
                return "WECHAT_QR"; // 小额走扫码支付
            }
        } else if ("ALIPAY".equals(channel)) {
            if (amount.compareTo(new BigDecimal("1000")) > 0) {
                return "ALIPAY_BANK";
            } else {
                return "ALIPAY_QR";
            }
        } else {
            return channel; // 其他渠道直接使用
        }
    }
    
    /**
     * 生成交易号
     */
    private String generateTradeNo() {
        return "TRD" + System.currentTimeMillis() + String.format("%04d", (int)(Math.random() * 10000));
    }
    
    /**
     * 查询渠道状态（模拟）
     */
    private String queryChannelStatus(String tradeNo) {
        // 模拟查询支付渠道状态
        // 实际项目中应该调用具体的支付渠道API
        if (tradeNo.startsWith("TRD")) {
            // 模拟80%的概率交易成功
            if (Math.random() < 0.8) {
                return "SUCCESS";
            } else {
                return "FAILED";
            }
        }
        return null;
    }
}
